package com.ylbh.modules.member.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ylbh.common.exception.NormalException;
import com.ylbh.common.pojo.member.dto.BusinessAnalysisDTO;
import com.ylbh.common.pojo.member.dto.MemberDTO;
import com.ylbh.common.pojo.member.vo.*;
import com.ylbh.common.utils.ExcelUtils;
import com.ylbh.common.utils.FastJsonUtil;
import com.ylbh.common.utils.PageUtils;
import com.ylbh.modules.member.mapper.MembershipAnalysisMapper;
import com.ylbh.modules.member.service.MembershipAnalysisService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author: czx
 * @date: 2019/07/24 11:27
 * 会员分析
 */
@Service
public class MembershipAnalysisServiceImpl extends ServiceImpl<MembershipAnalysisMapper, MemberDTO> implements MembershipAnalysisService {

    @Autowired
    private MembershipAnalysisMapper membershipAnalysisMapper;

    /**
     * 会员活跃度列表
     * @return
     */
    @Override
    public PageUtils queryMembershipActivityList(BusinessAnalysisDTO businessAnalysisDTO) throws IOException {
        Page<Integer> page = new Page<>(businessAnalysisDTO.getPage(), businessAnalysisDTO.getLimit());
        List<MembershipActivityVO> list = membershipAnalysisMapper.selectMembershipActivityList(businessAnalysisDTO, page);
        for (MembershipActivityVO vo : list) {
            // 如果用户登录过，则根据用户的Ip去查询用户登录所在的地址信息
            if (!StringUtils.isEmpty(vo.getIp())) {
                String ip = vo.getIp();
                String url = "http://api.k780.com/?app=ip.get&ip=" + ip + "&appkey=30514&sign=54d641f4f489d9595b241c669f88be6d&format=json";
                URL u=new URL(url);
                InputStream in=u.openStream();
                ByteArrayOutputStream out=new ByteArrayOutputStream();
                try {
                    byte buf[]=new byte[1024];
                    int read = 0;
                    while ((read = in.read(buf)) > 0) {
                        out.write(buf, 0, read);
                    }
                }  finally {
                    if (in != null) {
                        in.close();
                    }
                }
                byte b[]=out.toByteArray( );
                JSONObject jsonObject = JSONObject.parseObject(new String(b,"utf-8"));
                Object result = jsonObject.get("result");
                if (null != result) {
                    IpToAddressVO bean = FastJsonUtil.toBean(result.toString(), IpToAddressVO.class);
                    vo.setAddress(bean.getAtt());
                } else {
                    vo.setAddress(vo.getIp());
                }
            }

            // 根据用户的id在查询出用户最近一次在平台消费的时间和消费的金额
            List<ConsumptionInformationVO> pay = membershipAnalysisMapper.selectConsumptionInformation(vo.getId());
            if (pay.size() > 0) {
                vo.setPayDate(pay.get(0).getPayDate());
                vo.setPayAmountOfMoney(pay.get(0).getPayAmountOfMoney());
                vo.setPayType(pay.get(0).getPayType());
            }
        }
        return new PageUtils(new Page<MembershipActivityVO>().setRecords(list).setTotal(page.getTotal()));
    }

    /**
     * 联盟店消费信息列表
     * @param businessAnalysisDTO
     * @return
     */
    @Override
    public PageUtils queryBusinessAnalysisList(BusinessAnalysisDTO businessAnalysisDTO) {
        Page<Integer> page = new Page<>(businessAnalysisDTO.getPage(), businessAnalysisDTO.getLimit());

        // 根据当前获得本周一的时间和当天的时间 ------》开始

        // 周一
        String monday = null;
        // 当天
        String sameday = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if(dayWeek==1){
            dayWeek = 8;
        }
        System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期
        monday = sdf.format(cal.getTime()) + " 23:59:59";
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();
        String weekBegin = sdf.format(mondayDate);
        System.out.println("所在周星期一的日期：" + weekBegin);
        sameday = weekBegin + " 00:00:00";
        // 根据当前获得本周一的时间和当天的时间 ------》结束

        // 获取本月一号的时间 ------》开始
        // 本月一号
        String january1st = null;
        Calendar cale = null;
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        january1st = sdf.format(cale.getTime()) + " 00:00:00";
        // 获取本月一号的时间 ------》结束

        List<BusinessAnalysisVO> vo = membershipAnalysisMapper.selectBusinessAnalysisList(businessAnalysisDTO, page);
        for (BusinessAnalysisVO bav : vo) {
            // 根据联盟店id去查询本月订单总数
            List<Integer> monthOrderTotal = membershipAnalysisMapper.selectMonthOrderTotal(bav.getId(), january1st, new Date());
            for (Integer month : monthOrderTotal) {
                if (null == bav.getMonthlyOrder())
                    bav.setMonthlyOrder(month);
                else
                    bav.setMonthlyOrder(bav.getMonthlyOrder() + month);
            }
            // 根据联盟店id去查询本周订单总数
            List<Integer> weeklyOrder = membershipAnalysisMapper.selectWeeklyOrderTotal(bav.getId(), monday, sameday);
            for (Integer week : weeklyOrder) {
                if (null == bav.getWeeklyOrder())
                    bav.setWeeklyOrder(week);
                else
                    bav.setWeeklyOrder(bav.getWeeklyOrder() + week);
            }
        }
        return new PageUtils(new Page<BusinessAnalysisVO>().setTotal(page.getTotal()).setRecords(vo));
    }

    /**
     * 商城订单信息列表
     * @param businessAnalysisDTO
     * @return
     */
    @Override
    public PageUtils queryGoodsAnalysisList(BusinessAnalysisDTO businessAnalysisDTO) {
        Page<Integer> page = new Page<>(businessAnalysisDTO.getPage(), businessAnalysisDTO.getLimit());
        // 根据当前获得本周一的时间和当天的时间 ------》开始

        // 当天
        String monday = null;
        // 周一
        String sameday = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if(dayWeek==1){
            dayWeek = 8;
        }
        System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期
        monday = sdf.format(cal.getTime()) + " 23:59:59";
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();
        String weekBegin = sdf.format(mondayDate);
        System.out.println("所在周星期一的日期：" + weekBegin);
        sameday = weekBegin + " 00:00:00";
        // 根据当前获得本周一的时间和当天的时间 ------》结束

        // 获取本月一号的时间 ------》开始
        // 本月一号
        String january1st = null;
        Calendar cale = null;
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        january1st = sdf.format(cale.getTime()) + " 00:00:00";
        // 获取本月一号的时间 ------》结束
        businessAnalysisDTO.setMonday(monday);
        businessAnalysisDTO.setSameday(sameday);
        businessAnalysisDTO.setJanuary1st(january1st);
        List<GoodsAnalysisVO> list = membershipAnalysisMapper.selectGoodsAnalysisList(businessAnalysisDTO, page);
        return new PageUtils(new Page<GoodsAnalysisVO>().setTotal(page.getTotal()).setRecords(list));
    }

    /**
     * 导出会员活跃度
     * @param request
     * @param response
     */
    @Override
    public void membershipActivityListExcel(HttpServletRequest request, HttpServletResponse response) throws NormalException {
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String keywords = request.getParameter("keywords");
        String userType = request.getParameter("userType");
        List<MembershipActivityListExcelVO> list = membershipAnalysisMapper.selectMembershipActivityListExcel(startTime, endTime, keywords, userType);
        for (MembershipActivityListExcelVO vo : list) {
            // 根据用户的id在查询出用户最近一次在平台消费的时间和消费的金额
            List<ConsumptionInformationVO> pay = membershipAnalysisMapper.selectConsumptionInformation(vo.getId().intValue());
            if (pay.size() > 0) {
                vo.setPayDate(pay.get(0).getPayDate());
                vo.setPayMoney(pay.get(0).getPayAmountOfMoney());
                vo.setPayType(pay.get(0).getPayType());
            }
        }
        ExcelUtils.exportExcel(list, "会员活跃度", "", MembershipActivityListExcelVO.class, System.currentTimeMillis() + ".xls", response);
    }

    /**
     * 商城订单分析导出
     * @param request
     * @param response
     */
    @Override
    public void orderAnalysisOfMallExcel(HttpServletRequest request, HttpServletResponse response) throws NormalException {
        String keywords = request.getParameter("keywords");
        String userType = request.getParameter("userType");
        String type = request.getParameter("type");
        // 当天
        String monday = null;
        // 周一
        String sameday = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if(dayWeek==1){
            dayWeek = 8;
        }
        System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期
        monday = sdf.format(cal.getTime()) + " 23:59:59";
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();
        String weekBegin = sdf.format(mondayDate);
        System.out.println("所在周星期一的日期：" + weekBegin);
        sameday = weekBegin + " 00:00:00";
        // 根据当前获得本周一的时间和当天的时间 ------》结束

        // 获取本月一号的时间 ------》开始
        // 本月一号
        String january1st = null;
        Calendar cale = null;
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        january1st = sdf.format(cale.getTime()) + " 00:00:00";
        // 获取本月一号的时间 ------》结束
        BusinessAnalysisDTO businessAnalysisDTO = new BusinessAnalysisDTO();
        businessAnalysisDTO.setMonday(monday);
        businessAnalysisDTO.setSameday(sameday);
        businessAnalysisDTO.setJanuary1st(january1st);
        businessAnalysisDTO.setKeywords(keywords);
        if (!StringUtils.isEmpty(type))
            businessAnalysisDTO.setType(Integer.parseInt(type));
        if (!StringUtils.isEmpty(userType))
            businessAnalysisDTO.setUserType(Integer.parseInt(userType));
        List<OrderAnalysisOfMallExcel> list = membershipAnalysisMapper.selectOrderAnalysisOfMallExcel(businessAnalysisDTO);
        ExcelUtils.exportExcel(list, "商城订单分析", "", OrderAnalysisOfMallExcel.class, System.currentTimeMillis() + ".xls", response);
    }

    /**
     * 联盟店订单分析导出
     * @param request
     * @param response
     */
    @Override
    public void orderAnalysisOfAllianceStores(HttpServletRequest request, HttpServletResponse response) throws NormalException {
        String userType = request.getParameter("userType");
        String type = request.getParameter("type");
        String keywords = request.getParameter("keywords");
        // 根据当前获得本周一的时间和当天的时间 ------》开始


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 当天
        String sameday = null;
        // 周一
        String monday = null;
        Calendar cal = Calendar.getInstance();
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayWeek==1) {
            dayWeek = 8;
        }
        monday = sdf.format(cal.getTime()) + " 23:59:59";
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();
        String weekBegin = sdf.format(mondayDate);
        sameday = weekBegin + " 00:00:00";
        // 根据当前获得本周一的时间和当天的时间 ------》结束

        // 获取本月一号的时间 ------》开始
        // 本月一号
        String january1st = null;
//        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        //获得日历   并把当前时间放入日历中
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        //计算当前月份-1
        calendar.add(Calendar.MONTH, -1);
        //设时间为当前月份的第一天
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        date = calendar.getTime();
        january1st = sdf.format(date) + " 00:00:00";
        BusinessAnalysisDTO businessAnalysisDTO = new BusinessAnalysisDTO();
        businessAnalysisDTO.setMonday(monday);
        businessAnalysisDTO.setSameday(sameday);
        businessAnalysisDTO.setJanuary1st(january1st);
        if (!StringUtils.isEmpty(userType))
            businessAnalysisDTO.setUserType(Integer.parseInt(userType));
        businessAnalysisDTO.setKeywords(keywords);
        if (!StringUtils.isEmpty(type))
            businessAnalysisDTO.setType(Integer.parseInt(type));
        // 获取本月一号的时间 ------》结束

        List<OrderAnalysisOfAllianceStoresExcel> vo = membershipAnalysisMapper.selectOrderAnalysisOfAllianceStores(businessAnalysisDTO);
        for (OrderAnalysisOfAllianceStoresExcel bav : vo) {
            // 根据联盟店id去查询这本月和上月订单总数
            List<Integer> monthOrderTotal = membershipAnalysisMapper.selectMonthOrderTotal(bav.getId(), january1st, new Date());
            for (Integer month : monthOrderTotal) {
                if (null == bav.getMonthlyOrder())
                    bav.setMonthlyOrder(month);
                else
                    bav.setMonthlyOrder(bav.getMonthlyOrder() + month);
            }
            // 根据联盟店id去查询本周订单总数
            List<Integer> weeklyOrder = membershipAnalysisMapper.selectWeeklyOrderTotal(bav.getId(), monday, sameday);
            for (Integer week : weeklyOrder) {
                if (null == bav.getWeeklyOrder())
                    bav.setWeeklyOrder(week);
                else
                    bav.setWeeklyOrder(bav.getWeeklyOrder() + week);
            }
        }
        ExcelUtils.exportExcel(vo, "联盟店订单分析", "", OrderAnalysisOfAllianceStoresExcel.class, System.currentTimeMillis() + ".xls", response);
    }

}
